let arr = [1,3,['a','b',['1q','2w',['你好','不好',['wqn','ewr']]]]];

// 数组拉平几种方式
// 第一种：拉平，返回一个新数组
Array.prototype.flata = function(){
    if(!Array.isArray(this)){
        return []
    }
    function handArr (arr){
        let n1 = []
        arr.forEach(item=>{
            if(Array.isArray(item)){
                n1.push(...handArr(item))
            }else{
                n1.push(item)
            }
        })
        return n1
    }
    return handArr(this)
}
console.log(arr.flata())

// 第二种方法
console.log(arr.flat(Infinity),'--2')

// 第三种方法 reduce((上次一次，当前，下标，数组)=>{},  初始值)
function parr(arr){
    return arr.reduce((prev,now)=>{
        return prev.concat(Array.isArray(now)?parr(now):now)
    },[])
}
console.log(parr(arr))

// 第四种方式toString 会把数组中数字转换为字符串
function parr1 (arr){
    return arr.toString().split(',')
}
console.log(parr1(arr))

// 第五种方式 some
function parr2 (arr) { // arr中有数组，则解构一层
    while(arr.some(i=>Array.isArray(i))){
        arr = [].concat(...arr)
    }
    return arr;
}
console.log(parr2(arr),'-=--2')

// 第六种
function parr4(arr){
    let str = JSON.stringify(arr)
    reg = /\[|\]/g
    return JSON.parse('['+str.replace(reg,'')+']')
}
console.log(parr4(arr),'==reg')




// 数组去重
let repeat = [1,3,5,7,8,5,7,8,3,1];

// set
let res1= Array.from(new Set(repeat))
console.log(res1,'---set')

// reduce
function qc(arr){
    return arr.reduce((prev,now)=>{
        if(!prev.includes(now)){
            prev.push(now)
        }
        return prev
    },[])
}
console.log(qc(repeat),'---reduce')

// 循环
function forArr(arr){
    let jsons = {}
    arr.forEach(item=>{
        if(!jsons[item]){
            jsons[item]=item
        }
    })
    return Object.values(jsons)
}
console.log(forArr(repeat),'----json values')

// includes
function arrTwo(arr){
    let n = []
    arr.forEach(item=>{
        if(!n.includes(item)){
            n.push(item)
        }
    })
    return n;
}
console.log(arrTwo(repeat),'--includes')

// indexof

function indexOfs(arr){
    let s = []
    arr.forEach(item=>{
        if(s.indexOf(item) == -1){
            s.push(item)
        }
    })
    return s
}
console.log(indexOfs(repeat),'--indexOf')

// filter
function file(arr){
    return arr.filter((item,index)=>{
        return arr.indexOf(item) == index
    })
}

console.log(file(repeat),'--filter')

// filter 的实现 ，循环元素，并执行方法，为true的则返回

Array.prototype.myFilter=function(fun,thisArg){
    // 缺少this指向的对象，可省略 thisArg

    // 缺少数组验证
    if(!Array.isArray(this)){
        throw Error('this is no array')
    }
    // 缺少回调函数验证
    if (typeof fun !== 'function'){
        throw Error('callback is not function')
    }
    
    // 长度没有提出
    // 没有传回下标，数组
    let r = []
    let len = this.length;
    for (let i=0; i<len; i++){
        if(fun.call(thisArg,this[i],i,this)){
            r.push(this[i])
        }
    }
    return r
}
console.log([1,3,2,9].myFilter(item=>item>5),'---filter2')


// bind函数 改变this指向，并返回一个函数
function abc(...arg){
    let s = 0;
    let mergeArr = [...this, ...arg]
    mergeArr.forEach(item=>{
        s+=item
    })
    return s;
}

arr = [1,2,3]
let res = abc.bind(arr,2,3,4)
console.log(res(10),'----1')

function abind(fn, that, ...argu){
    return function(...argus){
        let mergeArr = [...argu,...argus]
        return fn.apply(that,mergeArr)
    }
}

let res5 = abind(abc,arr,2,3,4)
console.log(res5(10),'=----2')


function bind(fn, context, ...args) {
  function boundFn(...newArgs) {
    const mergedArgs = [...args, ...newArgs];
    
    if (this instanceof boundFn) {
      // 创建一个新对象，继承原函数的原型
      const instance = Object.create(fn.prototype);
      const result = fn.apply(instance, mergedArgs);
      
      // 如果原函数返回对象，则返回该对象；否则返回新创建的实例
      return result instanceof Object ? result : instance;
    }
    
    return fn.apply(context, mergedArgs);
  }
  
  // 直接修改返回函数的原型，这种方式存在一定问题，但简化了实现
  boundFn.prototype = fn.prototype;
  
  return boundFn;
}

let res6 = abind(abc,arr,2,3,4)
console.log(res6(10),'=----3')



function myCall(fn,that,...argu){
    if(that == null || that == undefined){
        that = window
    }
    that = Object(that)
    that[fn] = fn;
    let res = that[fn](...argu)
    delete that[fn]
    return res
}

console.log(myCall(abc,repeat,4,5,6),'---2')

// Promise.all([]).then().catch

function promiseAll(argu = []){
    return new Promise((resolve,reject)=>{
        let result =[]
        let index = 0;
        argu.forEach((item,i)=>{
            Promise.resolve(item).then(res=>{
                result[i] = res;
                index+=1
                if(index == argu.length){
                    resolve(result)
                }
            }).catch(e=>{
                reject(e)
            })
        })
    })
}
let p1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject(4)
    })
})
let p2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(5)
    },3000)
})
let p3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject(6)
    },1000)
})
let p4 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('error')
    },4000)
    
})
promiseAll([p1,p2,p3,p4]).then(res=>{
    console.log(res,'----自定义promise。all方法')
}).catch(e=>{
    console.log(e,'---自定义promise.all方法 faild')
})


// 手写allsettled
// 传入的promise都执行完毕，不管对错，在res中都会有相对应的返回值对象
Promise.allSettled([p1,p2,p3,p4]).then(res=>{
    console.log(res,'=--allsettled')
})
function myAllSettled(arr = []){
    return new Promise((resolve,reject)=>{
        let res = []
        let index = 0
        arr.forEach((item,i)=>{
            Promise.resolve(item).then((value)=>{
                index+=1
                res.push({status:'fulfilled', key:value})
                if(index == arr.length){
                    resolve(res)
                }
            },(e)=>{
                index+=1
                res.push({status:'faile', key:e})
                if(index == arr.length){
                    resolve(res)
                }
            })
        })
    })
}
myAllSettled([p1,p2,p3,p4]).then(res=>{
    console.log(res,'====自定义promise.settled')

})



// any 执行传入的promise，有一个成功了则结束状态
// Promise.any([p1,p2,p3,p4]).then(res=>{
//     console.log(res,'---any')
// }).catch(e=>{
//     console.log(e,'--any error')
// })

function myAny(arr = []){
    return new Promise((resolve,reject)=>{
        let errors =[]
        let index = 0
        arr.forEach((item,i)=>{
            Promise.resolve(item).then(res=>{
                index+=1
                resolve(res)
            }).catch(e=>{
                errors[i] = e;
                index+=1
                if(index == arr.length){
                    reject(errors)
                }
            })
        })
    })
}
myAny([p1,p2,p3,p4]).then(res=>{
    console.log(res,'====自定义myAny')
}).catch(e=>{
    console.log(e,'---e--自定义myAny')
})



// 执行传入的promise数组，有一个执行结束，则结束状态，并返回相对应的值
// Promise.race([p1,p2,p3,p4]).then(res=>{
//     console.log(res,'===reace')
// }).catch(e=>{
//     console.log(e,'--reace')
// })

function myRace(arr=[]){
    return new Promise((resolve,reject)=>{
        arr.forEach((item)=>{
            Promise.resolve(item).then(res=>{
                resolve(res)
            },e=>{
                reject(e)
            })
        })
    })
}
myRace([p1,p2,p3,p4]).then(res=>{
    console.log(res,'====myRace')
}).catch(e=>{
    console.log(e,'======e myRace')
})

// promise.try  与。try catch 相同
function amd(a,b){
    // console.log(sdfjsk)
    return a+b;
}
Promise.try(amd,1).then(res=>{console.log(res,'---try')}).catch(e=>{console.log(e)})

class NotPromise {
  constructor(executor) {
    // “resolve”和“reject”函数和原生的 promise 的行为完全不同
    // 但 Promise.withResolvers() 只是返回它们，就像是原生的 promise 一样
    executor(
      (value) => console.log("以", value, "解决"),
      (reason) => console.log("以", reason, "拒绝"),
    );
  }
}
let {promise,resolve,reject} = Promise.withResolvers.call(NotPromise)
console.log(promise,'==>',resolve,'===>',reject)
